#include <iostream>
#include <string>
#include <chrono>
#include <map>
#include <mysql/mysql.h>


int main(int argc, char** argv)
{

    MYSQL mysql;
    mysql_library_init(0, nullptr, nullptr);
    mysql_init(&mysql);

    std::string host = "127.0.0.1";
    //std::string host = "192.168.0.203";
    std::string user = "mysql_test";
    std::string pass = "123456";
    std::string db   = "mysql_test";

    int timeout = 3;
    int ret = mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
    if (0 != ret)
    {
        std::cout << "mysql options  fialed!" << mysql_error(&mysql) << std::endl;
    }


    if (nullptr ==  mysql_real_connect(&mysql, host.c_str(), user.c_str(), pass.c_str(), db.c_str(), 3306, nullptr, 0))
    {
        std::cout << "mysql connect fialed! " << mysql_error(&mysql) << std::endl;
        return 1;
    }

    if (mysql_ping(&mysql) != 0) 
    {
        std::cout << "Connection lost, reconnecting..." << std::endl;
        mysql_close(&mysql);
        // 重新初始化并连接
        return 1;
    }

    //1 创建表 

    std::string sql_create_t_image = "CREATE TABLE IF NOT EXISTS `t_image` (\
                `id` int AUTO_INCREMENT,\
                `name` varchar(1024),\
                `path` varchar(1024),\
                `size` int,\
                PRIMARY KEY(`id`)\
            );";


    if (0 != mysql_query(&mysql, sql_create_t_image.c_str()))
    {
        std::cout << "mysql query error: " << mysql_error(&mysql) << std::endl;
        return 1;
    }


    // 清空并让id从 1 开始
    std::string sql = "truncate t_image";
    if (0 != mysql_query(&mysql, sql.c_str()))
    {
        std::cout << "mysql truncate error: " << mysql_error(&mysql) << std::endl;
    }


    auto old_time = std::chrono::steady_clock::now();
    // 插入数据
    //for (int i = 0; i < 1000; i++)
    {
        std::string sql_insert = "insert `t_image` (`name`, `path`, `size`) values('test.jpg', 'd:/img/test";
       //sql_insert += std::to_string(i);
        sql_insert += ".jpg', '1024')";

    
        ret = mysql_query(&mysql, sql_insert.c_str());
        if (0 != ret)
        {   
            std::cout <<  "insert error: " << mysql_error(&mysql);
            return 1;
        }
        // 返回了影响数据数量
        int count = mysql_affected_rows(&mysql);
        // 返回插入数据的行号
        std::cout << "mysql affected row: " << count << "id " << mysql_insert_id(&mysql ) << std::endl;
    }
    
    auto new_time = std::chrono::steady_clock::now();

    std::cout << "time: " << std::chrono::duration_cast<std::chrono::milliseconds>(new_time - old_time).count() << "ms\n";

    // 修改数据
    std::string sql_update = "update t_image set `name`='test2.png', `size`=10000 where `id` = 1;";

    if (0 != mysql_query(&mysql, sql_update.c_str()))
    {
        std::cout <<  "update error: " << mysql_error(&mysql);
        return 1;
    }

    std::map<std::string, std::string> kv;
    kv["name"] = "image_update.png";
    kv["size"] = "5000";

    std::string where = " where id = 2;";
    std::string sql_update_map = "update `t_image` set ";
    std::string tmp = "";
    for (auto it = kv.begin(); it != kv.end(); ++it)
    {
        tmp += "`";
        tmp += it->first;
        tmp += "`='";
        tmp += it->second;
        tmp += "',";
    }
    tmp += "id=id";
    sql_update_map += tmp;
    sql_update_map += where;
    std::cout << sql_update_map << std::endl;
    if (0 != mysql_query(&mysql, sql_update_map.c_str()))
    {
        std::cout <<  "update map error: " << mysql_error(&mysql) << std::endl;
    }

    // 清理数据
    // delete from t_image         OPTIMIZE TABLE t_image 清理磁盘空间 会产生锁
    // truncate t_image             真的磁盘清理空间
    // drop table t_image           真的磁盘清理空间

    
    std::string sql_delete = "delete from t_image";
    if (0 != mysql_query(&mysql, sql_delete.c_str()))
    {
        std::cout << "delete  error: " << mysql_error(&mysql) << std::endl;
    }
 
    sql_delete = "delete from t_image where id = 1" ;
    if (0 != mysql_query(&mysql, sql_delete.c_str()))
    {
        std::cout << "delete  error: " << mysql_error(&mysql) << std::endl;
    }

    sql_delete = "OPTIMIZE TABLE t_image";
    if (0 != mysql_query(&mysql, sql_delete.c_str()))
    {
        std::cout << "delete  error: " << mysql_error(&mysql) << std::endl;
    }

    mysql_close(&mysql);
    mysql_library_end();
    return 0;
}
